package com.pawernode.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;

/**
 * 消息服务类，负责发送消息到 RabbitMQ
 * 实现了 RabbitTemplate.ConfirmCallback 接口以接收消息确认回调
 */
@Service
@Slf4j
public class MessageService implements RabbitTemplate.ConfirmCallback{

    // 这就是模板方法设计模式
    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 在容器启动的时候执行，相当于初始化作用
     * 设置消息模板的确认回调为当前类实例
     */
    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
    }

    /**
     * 发送消息到 RabbitMQ
     * 构建消息，发送带有确认信息的订单数据
     */
    public void sendMsg() {
        // 构建消息内容
        Message message = MessageBuilder.withBody("hello rabbitmq".getBytes()).build();
        // 创建关联数据，用于确认消息是否发送成功
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId("order_123456"); // 发送订单信息
        // 发送消息，带有确认数据
        rabbitTemplate.convertAndSend("exchange.confirm.2", "info", message,correlationData);
        log.info("消息发送完毕，发送时间为：{}", new Date());
    }

    /**
     * 消息发送确认回调方法
     *
     * @param correlationData 发送消息时附带的关联数据，用于标识消息
     * @param ack 消息发送结果，true 表示发送成功，false 表示发送失败
     * @param cause 发送失败的原因，如果发送成功则为 null
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            log.info("消息发送成功");
            return;
        } else {
            // ack 为 false 表示没有到达交换机
            log.error("消息发送失败，原因：{}", cause);
        }
    }
}
